/*
 * Copyright 2011 Michele Mancioppi [michele.mancioppi@gmail.com]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cave.nice.testMessage.reports;

import java.util.Date;
import java.util.List;

import org.joda.time.DateTime;
import org.joda.time.Minutes;

import cave.nice.testMessage.data.Test;
import cave.nice.testMessage.data.VerifiedAccount;

import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.users.User;

public class ReportsGenerator {

	public enum ReportingMedium {
		GMail, GTalk
	}

	public enum ReportType {
		TEXT_HTML, TEXT_PLAIN
	}

	public static String getReport(User user, VerifiedAccount account, List<Test> openTests, ReportType reportType, DateTime time) {
		switch (reportType) {
		case TEXT_HTML:
			return getHTMLReport(user, account, openTests, time);
		case TEXT_PLAIN:
			return getXMPPReport(user, account, openTests, time);
		}

		throw new UnsupportedOperationException("Unsupported report type: "
				+ reportType);
	}

	private static String getXMPPReport(User user, VerifiedAccount account, List<Test> openTests, DateTime currentDate) {
		StringBuffer sb = new StringBuffer();
		sb.append("Hi ");
		sb.append(user.getNickname());
		sb.append(',');
		sb.append('\n');

		if (openTests.isEmpty()) {
			sb.append("There are no open tests with your account '");
			sb.append(account.getEmailAddress());
			sb.append("'. Things seems to be going really well!");
		} else {
			sb.append("There are the following open tests listed under your account '");
			sb.append(account.getEmailAddress());
			sb.append("':");
			sb.append('\n');
			for (Test test : openTests) {
				int min = getOverdueBy(currentDate, test.getDate());

				sb.append("* id: ");
				sb.append(test.getIdentifier());
				sb.append('\n');
				sb.append("  sent on: ");
				sb.append(test.getDate());
				sb.append('\n');
				sb.append("  overdue by: ");
				sb.append(min);
				sb.append(" minutes");
				sb.append('\n');
			}
		}

		return sb.toString();
	}

	private static String getHTMLReport(User user, VerifiedAccount account, List<Test> openTests, DateTime currentDate) {
		StringBuffer sb = new StringBuffer();
		sb.append("<html><body>");
		sb.append("<p>Report for the account: ");
		sb.append(account.getEmailAddress());
		sb.append("</p>");
		sb.append('\n');

		if (openTests.isEmpty()) {
			sb.append("<p>No open tests (things should be going really well!)</p>");
		} else {
			sb.append("<p>The following tests are pending:</p>");
			sb.append('\n');
			sb.append("<table>");
			sb.append('\n');
			sb.append("<thead><th>Test Id:</th><th>Sent on:</th><th>Overdue by:</th></thead>");
			sb.append('\n');
			sb.append("<tbody>");
			for (Test test : openTests) {
				int min = getOverdueBy(currentDate, test.getDate());

				sb.append("<tr>");
				sb.append("<td>");
				sb.append(KeyFactory.keyToString(test.getIdentifier()));
				sb.append("</td>");
				sb.append("<td>");
				sb.append(test.getDate());
				sb.append("</td>");
				sb.append("<td>");
				sb.append(min);
				sb.append(" minutes");
				sb.append("</td>");
				sb.append("</tr>");
				sb.append('\n');
			}
		}
		sb.append("</tbody>");
		sb.append("</table>");
		sb.append("</body></html>");

		return sb.toString();
	}

	public final static int getOverdueBy(DateTime currentTime, Date testDate) {
		return Minutes.minutesBetween(new DateTime(testDate), currentTime)
				.getMinutes();
	}

}
